#ifndef _LOG_HELPER_H
#define _LOG_HELPER_H

#include <stdint.h>
#include <sstream>
#include <iostream>
//#define Use_OutputDebugString
#ifdef Use_OutputDebugString
    #include <windows.h>
#elif defined(Use_QDebug)
    #include <QDebug>
#endif

enum eLogLevel
{
	eDisable = -1,
	eInfo = 0,
	eDebug = 1,
	eWarning = 2,
	eFatal = 3,
};

/**
* @brief
*
*/
class LogWriter{
public:
	/**
	* @brief
	*
	*/
	LogWriter() {}
	/**
	* @brief
	*
	*/
	LogWriter(int32_t level, const char* func, uint32_t line)
		:m_level(level), m_func(func), m_line(line)
	{}
	/**
	* @brief
	*
	* @param )
	* @return LogWriter &operator
	*/
	inline LogWriter& operator<<(std::ostream& (*log)(std::ostream&)) {
		m_ss << log;
		return *this;
	}
	template <typename T>
	/**
	* @brief
	*
	* @param log
	* @return LogWriter &operator
	*/
	inline LogWriter& operator<<(const T& log) {
		if (m_ss.str().length() > 0){
			m_ss << " ";
		}
		m_ss << log;
		return *this;
	}

	/**
	* @brief
	*
	*/
	~LogWriter()
	{
		std::ostringstream oss;
		oss << "[ " << m_func << ":" << m_line << "] - ";

        switch (m_level)
        {

        case (int32_t)eInfo:
            oss << "INFO-";
            break;
        case (int32_t)eDebug:
            oss << "DEBUG-";
            break;
        case (int32_t)eFatal:
            oss << "ERROR-";
            break;
        case (int32_t)eDisable:
        default:
            break;
        }

        oss << "[ " << m_func << ":" << m_line << "] - ";
        oss << m_ss.str();
#ifdef Use_OutputDebugString
        oss << std::endl;
        OutputDebugStringA(oss.str().c_str());
#elif defined (Use_QDebug)
        qDebug() << oss.str().c_str();
#else
        std::cout << oss.str() << std::endl;
#endif

	}
private:
    int32_t m_level = (int32_t)eDebug;
	std::stringstream m_ss; 
	std::string m_func;
	uint32_t m_line;
};

#define LOG(x)		LogWriter(x, __FUNCTION__, __LINE__)

#define	INFO	LogWriter(eInfo, __FUNCTION__, __LINE__)
#define DEBUG  LogWriter(eDebug, __FUNCTION__, __LINE__)
#define ERR	LogWriter(eFatal, __FUNCTION__, __LINE__)

#endif
